home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / fsp-2.7 / fsp-2 / fsp / client / lib.c next >
Encoding:
C/C++ Source or Header  |  1993-05-21  |  4.5 KB  |  155 lines

  1.     /*********************************************************************\
  2.     *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  3.     *                                                                     *
  4.     *  You may copy or modify this file in any manner you wish, provided  *
  5.     *  that this notice is always included, and that you hold the author  *
  6.     *  harmless for any loss or damage resulting from the installation or *
  7.     *  use of this software.                                              *
  8.     \*********************************************************************/
  9.  
  10. #include "tweak.h"
  11. #include "client_def.h"
  12. #include "c_extern.h"
  13. #include "co_extern.h"
  14.  
  15. extern int errno;
  16.  
  17. static int myfd;
  18. static struct sockaddr_in server_addr;
  19. static unsigned short myseq = 0;
  20. static unsigned short key;
  21.  
  22. int client_trace = 0;
  23. int client_intr_state = 0;
  24. unsigned long target_delay = MIN_DELAY;    /* expected max delay     */
  25. unsigned long busy_delay = MIN_DELAY;    /* busy retransmit timer */
  26. unsigned long idle_delay = MIN_DELAY;    /* idle retransmit timer */
  27. unsigned long udp_sent_time;
  28.  
  29. UBUF *client_interact PROTO6(unsigned int, cmd, unsigned long, pos,
  30.                  unsigned int, l1, unsigned char *, p1,
  31.                  unsigned int, l2, unsigned char *, p2)
  32. {
  33.   struct sockaddr_in from;
  34.   UBUF sbuf;
  35.   static UBUF rbuf;
  36.   unsigned char *s, *t, *d, seq0, seq1;
  37.   unsigned u, n, sum, mask, mlen, rlen;
  38.   int retval, bytes, retry_send, retry_recv;
  39.   unsigned long w_delay;
  40.   
  41.   sbuf.cmd = cmd;
  42.   BB_WRITE2(sbuf.bb_len,l1);
  43.   BB_WRITE4(sbuf.bb_pos,pos);
  44.   
  45.   client_intr_state = 1;
  46.   
  47.   for(u = l1, d = (unsigned char *) sbuf.buf; u--; *d++ = *p1++);
  48.   for(u = l2; u--; *d++ = *p2++);
  49.   mlen = d - (unsigned char *) &sbuf;
  50.   
  51.   key = client_get_key();
  52.   
  53.   for(retry_send = 0; ; retry_send++) {
  54.     BB_WRITE2(sbuf.bb_key,key);
  55.     sbuf.bb_seq[0] = seq0 = (myseq >> 8) & 0xff;
  56.     sbuf.bb_seq[1] = seq1 = (myseq & 0xfc) | (retry_send & 0x0003);
  57.     sbuf.sum = 0;
  58.     
  59.     for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++);
  60.     sbuf.sum = sum + (sum >> 8);
  61.       
  62.     switch(retry_send) {    /* adaptive retry delay adjustments */
  63.       case  0:
  64.         busy_delay = (target_delay+(busy_delay<<3)-busy_delay)>>3;
  65.     w_delay = busy_delay;
  66.     break;
  67.       case  1:
  68.     busy_delay = busy_delay + (busy_delay >> 1);
  69.     w_delay = busy_delay;
  70.     if(client_trace) write(2,"R",1); break;
  71.       
  72.       default:
  73. #ifdef CLIENT_TIMEOUT
  74.     if (!pos && retry_send >= env_timeout ) {
  75.       fprintf(stderr, "\rRemote server not responding.\n");
  76.       exit(1);
  77.     }
  78. #endif
  79.     if(idle_delay < 5*60*1000) idle_delay = idle_delay << 1;
  80.     w_delay = idle_delay;
  81.     if(client_trace) write(2,"I",1);
  82.     break;
  83.     }
  84.       
  85.     if(sendto(myfd,&sbuf,mlen,0,(struct sockaddr *)&server_addr,
  86.           sizeof(server_addr)) == -1) {
  87.       perror("sendto");
  88.       exit(1);
  89.     }
  90.     udp_sent_time = time((time_t *) 0);
  91.     mask = 1 << myfd;
  92.       
  93.     for(retry_recv = 0; ; retry_recv++) {
  94.       if(retry_recv && client_trace) write(2,"E",1);
  95.       retval = _x_select(&mask, w_delay);
  96.       if((retval == -1) && (errno == EINTR)) continue;
  97.       if(retval == 1) { /* an incoming message is waiting */
  98.     bytes = sizeof(from);
  99.     if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
  100.                  (struct sockaddr *)&from, &bytes)) < UBUF_HSIZE)
  101.       continue;
  102.           
  103.     s = (unsigned char *) &rbuf;
  104.     d = s + bytes;
  105.     u = rbuf.sum; rbuf.sum = 0;
  106.     for(t = s, sum = 0; t < d; sum += *t++);
  107.     sum = (sum + (sum >> 8)) & 0xff;
  108.     if(sum != u) continue;  /* wrong check sum */
  109.           
  110.     rlen = BB_READ2(rbuf.bb_len);
  111.           
  112.     if( (rbuf.bb_seq[0] ^ seq0) ||
  113.        ((rbuf.bb_seq[1] ^ seq1)&0xfc)) continue;  /* wrong seq # */
  114.     if((int) (rlen+UBUF_HSIZE)  > bytes) continue;  /* truncated.  */
  115.           
  116.     myseq = (myseq + 0x0004) & 0xfffc;  /* seq for next request */
  117.     key = BB_READ2(rbuf.bb_key); /* key for next request */
  118.           
  119.     client_put_key(key);
  120.           
  121.     if(client_intr_state == 2) {
  122.       if(!key_persists) client_done();
  123.       exit(1);
  124.     }
  125.           
  126.     return(&rbuf);
  127.     
  128.       } else break;   /* go back to re-transmit buffer again */
  129.     }
  130.   }
  131. }
  132.  
  133. void init_client PROTO3(char *, host, int, port, int, myport)
  134. {
  135.   busy_delay = idle_delay = target_delay;
  136.   
  137.   if((myfd = _x_udp(&myport)) == -1) {
  138.     perror("socket open");
  139.     exit(1);
  140.   }
  141.   
  142.   if(_x_adr(host,port,&server_addr) == -1) {
  143.     perror("server addr");
  144.     exit(1);
  145.   } 
  146.   
  147.   client_init_key(server_addr.sin_addr.s_addr,port,getpid());
  148. }
  149.  
  150. int client_done PROTO0((void))
  151. {
  152.   (void) client_interact(CC_BYE, 0L, 0, (unsigned char *)NULLP, 0,
  153.              (unsigned char *)NULLP);
  154. }
  155.